package com.mida.app.report.utils;

import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.mida.dms.knw.entity.vo.BodyTreeVo;
import com.mida.dms.knw.entity.vo.KnwIndividualSoltVos;
import com.mida.dms.knw.entity.vo.KnwNoumenonVo;
import com.mida.dms.knw.entity.vo.KnwSlotVo;
import com.mida.dms.knw.vo.DocStructFragmentVo;
import com.mida.dms.knw.vo.DocStructSlotValueVo;
import com.mida.dms.knw.vo.DocStructTemplateSlotVo;
import com.mida.dms.knw.vo.RecommendDiagnosticVo;
import com.mida.dms.mdm.pojo.auto.MsdDataSet;
import com.mida.dms.mdm.pojo.auto.MsdDetailCodingSystem;
import com.mida.tool.common.result.ListResult;
import org.apache.commons.lang3.StringUtils;
import org.jetbrains.annotations.NotNull;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.mida.tool.common.result.BaseResult.buildListWarn;

/**
 * @ClassName: DocFastWriteUtil
 * @Description: TODO   数字患者工具类
 * @Author: wang xiao le
 * @Date: 2021/8/8 10:05
 **/
public class DocFastWriteUtil {

    private static final String TAG_LABEL = "TagLabel";
    private static final String WARN_MESSAGE_0001 = "该检查部位没有注册成概念";
    private static final String WARN_MESSAGE_0002 = "相关检查部位没有注册成概念";
    private static final long RELEASE_STATUS = 43736704971964416L;
    private static final String LONG_STRING = "|";
    private static final String ERROR_MESSAGE_0001 = "部位的soid为空";
    private static final String ERROR_MESSAGE_0002 = "概念的soid为空";
    private static final String ERROR_MESSAGE_0003 = "本体列表为空";
    private static final String COMMA = ",";
    private static final String IS_A_PART_OF = "is a part of";
    private static final long DCS_CHECK_TYPE_SOID = 1702L;
    private static final long DCS_IMAGE_DIAGNOSE_SOID = 20197039698608128L;
    private static final long DCS_SEX_SOID = 373L;


    /**
     * 设置对象
     *
     * @param list
     * @param mapDataSetName
     * @param mapDetailCodingSystemName
     */
    public static void setKnwNoumenonVo(List<KnwNoumenonVo> list, Map<Long, MsdDataSet> mapDataSetName, Map<Long, MsdDetailCodingSystem> mapDetailCodingSystemName) {
        list.stream().forEach(a -> {
            MsdDataSet msdDataSet;
            if (mapDataSetName.get(a.getNoumenonType()) != null) {
                msdDataSet = mapDataSetName.get(a.getNoumenonType());
                a.setNoumenonTypeName(msdDataSet.getDataSetMeaning());
            }

            if (mapDataSetName.get(a.getNoumenonSubType()) != null) {
                msdDataSet = mapDataSetName.get(a.getNoumenonSubType());
                a.setNoumenonSubTypeName(msdDataSet.getDataSetMeaning());
            }

            a.setPageTypeName(a.getNoumenonTypeName() + LONG_STRING + a.getNoumenonSubTypeName());

            a.getListKnwSlotVo().stream().forEach(b -> {
                MsdDataSet msdDataSetTmp;
                if (mapDataSetName.get(b.getDataType()) != null) {
                    msdDataSetTmp = mapDataSetName.get(b.getDataType());
                    b.setDataSetMeaning(msdDataSetTmp.getDataSetMeaning());
                }
                if (mapDataSetName.get(b.getUnit()) != null) {
                    msdDataSetTmp = mapDataSetName.get(b.getUnit());
                    b.setUnitName(msdDataSetTmp.getDataSetMeaning());
                    b.setUnitDescription(msdDataSetTmp.getDataSetDescription());
                }

                MsdDetailCodingSystem m;
                if (mapDetailCodingSystemName.get(b.getDerailCodingSystemSoid()) != null) {
                    m = mapDetailCodingSystemName.get(b.getDerailCodingSystemSoid());
                    b.setDerailCodingSystemName(m.getCnName());
                }
            });
        });
    }

    /**
     * 获取值集SOID的MAP和编码体系soid的MAP
     *
     * @param list
     * @param mapDataSetSoid
     * @param mapDetailCodingSystemSoid
     */
    public static void gainDsMapSoidAndDcsMapSoid(
            List<KnwNoumenonVo> list,
            Map<Long, Long> mapDataSetSoid,
            Map<Long, Long> mapDetailCodingSystemSoid) {
        list.stream().forEach(vo -> {
            // 设置值集map和编码体系map
            setDsMapAndDcsMap(vo, mapDataSetSoid, mapDetailCodingSystemSoid);
        });
    }


    /**
     * 设置返回对象
     *
     * @param list
     * @param listTmp
     * @param map
     * @param mapBodySoid
     */
    public static void setBodyTreeVoList(
            List<BodyTreeVo> list, List<BodyTreeVo> listTmp,
            Map<Long, Object> map, Map<Long, Long> mapBodySoid) {
        BodyTreeVo bodyTreeVo;
        // 设置返回对象
        for (BodyTreeVo b : listTmp) {
            if (b.getSourceNoumenonSoid() != null
                    && IS_A_PART_OF.equals(b.getPyCode())) {
                bodyTreeVo = new BodyTreeVo();
                bodyTreeVo.setNoumenonShowName(b.getNoumenonName());
                bodyTreeVo.setNoumenonSoid(b.getSourceNoumenonSoid());
                if (map.get(b.getConceptualSoid()) != null) {
                    bodyTreeVo.setRelatedSoids(String.valueOf(map.get(b.getConceptualSoid())));
                }

                if (mapBodySoid.get(b.getConceptualSoid()) != null) {
                    bodyTreeVo.setBodySoid(mapBodySoid.get(b.getConceptualSoid()));
                }

                bodyTreeVo.setCnt(b.getCnt());
                list.add(bodyTreeVo);
            }
        }
    }

    /**
     * 获取本体关系是 【is a part of】概念soid
     *
     * @param result
     * @param longList
     * @param listTmp
     * @return
     */
    public static boolean setConceptualSoidList(ListResult result, List<Long> longList, List<BodyTreeVo> listTmp) {
        // 获取本体关系是 【is a part of】概念soid
        for (BodyTreeVo b : listTmp) {
            if (b.getConceptualSoid() != null
                    && IS_A_PART_OF.equals(b.getPyCode())) {
                longList.add(b.getConceptualSoid());
            }
        }

        if (longList.size() == 0) {
            buildListWarn(result, WARN_MESSAGE_0002);
            return true;
        }
        return false;
    }


    /**
     * 验证部位soid
     *
     * @param vo
     * @param result
     * @return
     */
    public static boolean checkBodySoid(com.mida.dms.knw.vo.PatientInfoParameterVo vo,
                                        ListResult result) {
        if (StringUtils.isEmpty(vo.getBodySoid())) {
            buildListWarn(result, ERROR_MESSAGE_0001);
            return true;
        }
        return false;
    }


    /**
     * @return java.util.List<java.lang.Long>
     * @Author WXL
     * @Description  根据本体soid列表获取本体对应的概念、已经本体下的本性关系对应本体的soid
     * @Date 2021/8/8
     * @Param [conceptualSoids, listTmp]
     **/
    @NotNull
    public static List<Long> addConceptualSoidsAndNoumenonSoidsTmp(List<Long> conceptualSoids, List<BodyTreeVo> listTmp) {
        List<Long> noumenonSoidsTmp;
        noumenonSoidsTmp = new ArrayList<>();
        for (BodyTreeVo bt : listTmp) {
            if (bt.getConceptualSoid() != null) {
                conceptualSoids.add(bt.getConceptualSoid());
            }
            if (bt.getCnt() > 0) {
                if (bt.getSourceNoumenonSoid() != null) {
                    noumenonSoidsTmp.add(bt.getSourceNoumenonSoid());
                }
            }
        }
        return noumenonSoidsTmp;
    }


    /**
     * 验证概念
     *
     * @param result
     * @param conceptSoids
     * @return
     */
    public static boolean checkConceptSoids(ListResult result, List<Long> conceptSoids) {
        if (conceptSoids == null || conceptSoids.size() == 0) {
            buildListWarn(result, ERROR_MESSAGE_0002);
            return true;
        }
        return false;
    }


    /**
     * 设置诊断内容
     *
     * @param vo
     * @param mapTmp
     * @param listRecommendDiagnosticVo
     * @param mapExamServiceType
     */
    public static void setRecommendDiagnosticVo(com.mida.dms.knw.vo.PatientInfoParameterVo vo,
                                                Map<Long, Object> mapTmp,
                                                List<RecommendDiagnosticVo> listRecommendDiagnosticVo,
                                                Map<String, Object> mapExamServiceType) {
        RecommendDiagnosticVo recommendDiagnosticVo;
        List<KnwIndividualSoltVos> listTmp;
        for (Map.Entry<Long, Object> entry : mapTmp.entrySet()) {
            recommendDiagnosticVo = new RecommendDiagnosticVo();
            listTmp = new ArrayList<>();
            listTmp = (List<KnwIndividualSoltVos>) entry.getValue();
            String tmpStr = "";
            Long sex = null;
            List<DocStructFragmentVo> listDocStructFragmentVo = new ArrayList<DocStructFragmentVo>();
            DocStructFragmentVo docStructFragmentVo = new DocStructFragmentVo();
            docStructFragmentVo.setNoumenonSoid(listTmp.get(0).getNoumenonSoid());
            docStructFragmentVo.setTagName(TAG_LABEL);
            List<DocStructTemplateSlotVo> listDocStructTemplateSlotVo = new ArrayList<DocStructTemplateSlotVo>();

            boolean flg = false;
            for (KnwIndividualSoltVos v : listTmp) {
                DocStructTemplateSlotVo docStructTemplateSlotVo = setDocStructFragmentVoList(v);
                // 检查类型的场合
                if (v.getDerailCodingSystemSoid() != null
                        && v.getDerailCodingSystemSoid() == DCS_CHECK_TYPE_SOID
                        && v.getDataSetSoid() != null) {
                    // 检查类型不一致的场合
                    if (mapExamServiceType.get(v.getDataSetSoid().toString()) == null) {
                        continue;
                        // 检查类型一致的场合
                    } else {
                        flg = true;
                    }
                }

                // 段落片段Slot对象追加
                listDocStructTemplateSlotVo.add(docStructTemplateSlotVo);

                // 影像诊断编码体系的场合
                if (v.getDerailCodingSystemSoid() != null
                        && v.getDerailCodingSystemSoid() == DCS_IMAGE_DIAGNOSE_SOID) {
                    tmpStr = v.getIndividualName();
                    continue;
                }

                // 性别的场合
                if (v.getDerailCodingSystemSoid() != null
                        && v.getDerailCodingSystemSoid() == DCS_SEX_SOID
                        && v.getDataSetSoid() != null) {
                    sex = v.getDataSetSoid();
                    continue;
                }
            }
            docStructFragmentVo.setDocStructTemplateSlotVoList(listDocStructTemplateSlotVo);
            listDocStructFragmentVo.add(docStructFragmentVo);
            recommendDiagnosticVo.setDocStructFragmentVoList(listDocStructFragmentVo);
            if ((sex == null || sex == vo.getSexSoid()) && flg) {
                recommendDiagnosticVo.setRecommendDiagnosticContent(tmpStr);
                listRecommendDiagnosticVo.add(recommendDiagnosticVo);
            }
        }
    }

    /**
     * @return
     */
    public static DocStructTemplateSlotVo setDocStructFragmentVoList(KnwIndividualSoltVos v) {
        // 模板段落片段Slot
        DocStructTemplateSlotVo docStructTemplateSlotVo = new DocStructTemplateSlotVo();
        // 模板段落片段SlotValue
        DocStructSlotValueVo docStructSlotValueVo = new DocStructSlotValueVo();
        docStructSlotValueVo.setDataValue(v.getDataSetMeaning());
        docStructTemplateSlotVo.setTagName(TAG_LABEL);
        docStructTemplateSlotVo.setDocStructSlotValueVo(docStructSlotValueVo);

        docStructTemplateSlotVo.setSlotSoid(v.getSlotSoid());
        docStructTemplateSlotVo.setIndividualSoid(v.getIndividualSoid());
        docStructTemplateSlotVo.setIndividualName(v.getIndividualName());
        docStructTemplateSlotVo.setNoumenonSoid(v.getNoumenonSoid());

        return docStructTemplateSlotVo;
    }


    /**
     * 设置值集map和编码体系map
     *
     * @param a
     * @param mapDataSetSoid
     * @param mapDetailCodingSystemSoid
     */
    public static void setDsMapAndDcsMap(KnwNoumenonVo a,
                                         Map<Long, Long> mapDataSetSoid,
                                         Map<Long, Long> mapDetailCodingSystemSoid) {
        if (ObjectUtils.isNotEmpty(a.getNoumenonSubType())) {
            if (mapDataSetSoid.get(a.getNoumenonSubType()) == null) {
                mapDataSetSoid.put(a.getNoumenonSubType(), a.getNoumenonSubType());
            }
        }
        if (ObjectUtils.isNotEmpty(a.getNoumenonType())) {
            if (mapDataSetSoid.get(a.getNoumenonType()) == null) {
                mapDataSetSoid.put(a.getNoumenonType(), a.getNoumenonType());
            }
        }

        // 取得所有集值soid列表、以及编码体系soid列表
        setDsMapAndDcsMap(a.getListKnwSlotVo(), mapDataSetSoid, mapDetailCodingSystemSoid);
    }


    /**
     * 设置值集map和编码体系map
     *
     * @param list
     * @param mapDataSetSoid
     * @param mapDetailCodingSystemSoid
     */
    public static void setDsMapAndDcsMap(List<KnwSlotVo> list, Map<Long, Long> mapDataSetSoid, Map<Long, Long> mapDetailCodingSystemSoid) {
        list.stream().forEach(b -> {
            if (ObjectUtils.isNotEmpty(b.getDataType())) {
                if (mapDataSetSoid.get(b.getDataType()) == null) {
                    mapDataSetSoid.put(b.getDataType(), b.getDataType());
                }
            }
            if (ObjectUtils.isNotEmpty(b.getUnit())) {
                if (mapDataSetSoid.get(b.getUnit()) == null) {
                    mapDataSetSoid.put(b.getUnit(), b.getUnit());
                }
            }

            if (ObjectUtils.isNotEmpty(b.getDerailCodingSystemSoid())) {
                if (mapDetailCodingSystemSoid.get(b.getDerailCodingSystemSoid()) == null) {
                    mapDetailCodingSystemSoid.put(
                            b.getDerailCodingSystemSoid(), b.getDerailCodingSystemSoid());
                }
            }

        });
    }


}
